package main

import (
	"encoding/json"
	"fmt"
	"net"
	"strconv"
	"time"

	x "gitcode.com/shexk/xframe/plugin"
)

type Server struct {
	Server *TcpServer
	AppObj *x.AppObj
	//DataBus chan x.PluginMsg
}

func LoadPlugin() x.Plugin {
	return &Server{Server: NewTcpServer()}
}

func GetNanoID() uint64 {
	return uint64(time.Now().UnixNano()) //time.Now().UnixMilli()
}

type DBRequest struct {
	Name  string
	Value string
}

func (p *Server) Init(obj *x.AppObj) error {
	p.AppObj = obj

	return nil
}

func (p *Server) Start() error {
	// 实现具体逻辑
	ss := p.ReadKeyValue("TCP.Server.Port")
	port := StringToUint64(string(ss))
	p.Server = NewTcpServer()
	p.Server.Start(port)
	p.WriteLog(fmt.Sprintf("Start TcpServer Port=%d", port))
	p.Server.OnServerState = func(conn net.Conn, state int, err error, data []byte, datasize uint32) {
		v := x.Object{Type: x.Type_Topic, Name: Topic_Name}
		var res = x.PluginMsg{ID: x.GetMessageID(), Cmd: x.Command_TransPlugin,
			Sender:   x.Object{Type: x.Type_Plugin, Name: Plugin_Name},
			Receiver: []x.Object{v}}

		info := SocketInfo{ClientAddr: conn.RemoteAddr().String()}

		switch state {
		case TCP_STATE_CONNECTED:
			info.ClientState = "Connect"
		case TCP_STATE_DISCONNECTED:
			info.ClientState = "DisConnect"
		case TCP_STATE_DATA:
			info.ClientState = "Data"
			res.Data = make([]byte, datasize)
			copy(res.Data, data)
		case TCP_STATE_ERROR:
			info.ClientState = "Error"
		}
		if d, err := json.Marshal(info); err == nil {
			res.Option = string(d)
		}
		p.AppObj.DataBus <- &res
	}

	return nil
}
func (p *Server) Stop() error {
	// 实现具体逻辑
	fmt.Println("TcpServer Destroy")
	return nil
}

func StringToUint64(s string) uint64 {
	// 尝试解析为十进制uint64
	num, err := strconv.ParseUint(s, 10, 64)
	if err != nil {
		return 0
	}
	return num
}
func (p *Server) Receiver(dt *x.PluginMsg) {
	fmt.Println("[TcpServer] Receiver:", dt)
}
func (p *Server) ReadKeyValue(name string) string {
	if p.AppObj.DB == nil {
		return ""
	}

	rows, err := p.AppObj.DB.Query("Select value from KeyValue where Key='" + name + "'")
	if err != nil {
		fmt.Println("Read Record Error:" + err.Error())
		return ""
	}
	defer rows.Close()
	if rows.Next() {
		aes := ""
		if err = rows.Scan(&aes); err != nil {
			fmt.Println("Read Record Value Error:" + err.Error())
			return ""
		}
		return aes
	}
	return ""
}

const (
	Plugin_Name = "TcpServer"
	Topic_Name  = "TCP.Server.Topic"
)

func (p *Server) Meta() *x.PluginMeta {
	return x.NewPluginMeta(Plugin_Name, "1.0.0", "Shexk")
}
func (p *Server) WriteLog(log string) {
	obj := x.Object{Type: x.Type_Service, Name: "CommandCenter"}
	msg := x.PluginMsg{ID: x.GetMessageID(), Cmd: x.Command_Log, Sender: x.Object{Type: x.Type_Plugin, Name: p.Meta().Name},
		Receiver: []x.Object{obj},
		Option:   "", Data: []byte(log)}
	p.AppObj.DataBus <- &msg
}

func (p *Server) PostPluginMsg(option string, data []byte) {
	obj := x.Object{Type: x.Type_Service, Name: "CommandCenter"}
	msg := x.PluginMsg{ID: x.GetMessageID(), Cmd: x.Command_DB, Sender: x.Object{Type: x.Type_Plugin, Name: p.Meta().Name},
		Receiver: []x.Object{obj},
		Option:   option, Data: data}
	p.AppObj.DataBus <- &msg
}

type SocketInfo struct {
	ClientAddr  string
	ClientState string
}

//go build -buildmode=plugin -o tcpserver.so  .
